import * as Common from './common';

export function getRequest(url, headers, successCallback, errorCallback, async) {
    return request(url, 'GET', null, headers, successCallback, errorCallback, async);
}

export function postRequest(url, data, headers, successCallback, errorCallback, async) {
    return request(url, 'POST', data, headers, successCallback, errorCallback, async);
}

export function deleteRequest(url, headers, successCallback, errorCallback, async) {
    return request(url, 'DELETE', null, headers, successCallback, errorCallback, async);
}

export function putRequest(url, data, headers, successCallback, errorCallback, async) {
    return request(url, 'PUT', data, headers, successCallback, errorCallback, async);
}

export function promisePostRequest(url, headers, data) {
    return promiseRequest(url, 'POST', headers, data);
}

export function promisePutRequest(url, headers, data) {
    return promiseRequest(url, 'PUT', headers, data);
}

export function promiseRequest(url, method, headers, data) {
    if (window.fetch) return fetchRequest(url, method, headers, data);
    if (method === 'POST' || method === 'PUT') {
        headers = headers || {};
        headers["Content-Type"] = "application/json; charset=utf-8";
    }

    return new Promise((resolve) => {
        try {
            request(url, method, data ? JSON.stringify(data) : null, headers, (res) => resolve(res), (message) => resolve({ isSuccess: false, message }), false);
        }
        catch (error) {
            resolve({ isSuccess: false, message: error.message || error })
        }
    });
}

export function promiseGetRequest(url, headers) {
    return promiseRequest(url, 'GET', headers);
}

export function promiseDeleteRequest(url, headers) {
    return promiseRequest(url, 'DELETE', headers);
}

function fetchRequest(url, method, headers, data, isFormData) {
    try {
        headers = headers || {};
        let body = null;
        if (isFormData) body = data;
        else if (method === "POST") {
            headers["Content-Type"] = "application/json; charset=utf-8";
            body = JSON.stringify(data);
        }
        url = getFullUrl(url);
        return fetch(url, {
            method,
            headers,
            body
        }).then(res => setResult(res)).then(d => Promise.resolve(d), res => getErrorResponse(res));
    }
    catch (error) {
        console.warn("request/fetchRequest", error);
        return Promise.resolve({ isSuccess: false, message: error.message || error })
    }
}

function getErrorResponse(res) {
    const msg = res && res.message ? res.message : res;
    return Promise.resolve({ isSuccess: false, message: msg });
}


function getFullUrl(url) {
    return Common.addUrlRandom(url);
}

function setResult(res) {
    return res.ok ? res.json() : Promise.reject(res.status + ":" + (Common.isNullOrEmptyReturnDefault(res.statusText, "请求错误！")));
}

export function promisePostFormData(url, headers, formData) {
    if (window.fetch) return fetchRequest(url, 'POST', headers, formData, true);
    return new Promise((resolve) => {
        try {
            postRequest(url, formData, headers, (res) => resolve(res), (message) => resolve({ isSuccess: false, message }), false);
        }
        catch (error) {
            resolve({ isSuccess: false, message: error.message || error })
        }
    });
}


function request(url, method, data, headers, successCallback, errorCallback, async) {
    const xmlHttp = createRequest();

    url = Common.addUrlRandom(url);

    //打开请求
    xmlHttp.open(method, url, async);

    if (headers) {
        for (const key in headers) {
            xmlHttp.setRequestHeader(key, headers[key]);
        }
    }

    //处理请求响应返回
    xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState === 4) {
            if (xmlHttp.status === 200) {
                successCallback && successCallback(JSON.parse(xmlHttp.responseText));
            }
            else {
                const msg = xmlHttp.statusText ? xmlHttp.status + ":" + xmlHttp.statusText : xmlHttp.responseText;
                errorCallback && errorCallback(msg);
            }
        }
    };

    //发送请求
    xmlHttp.send(data);

    return xmlHttp;
}

//创建请求对象
function createRequest() {
    return new XMLHttpRequest();
}
